using Microsoft.Extensions.Options;
using RabbitMQ.Client;
using RabbitMQ.Client.Events;
using System.Collections.Concurrent;
using System.Text;
using System.Text.Json;
using WebRtcProject.Models;
using WebRtcProject.Models.Configuration;
using WebRtcProject.Models.Messages;

namespace WebRtcProject.Services
{
    /// <summary>
    /// WebRTC 专用 RabbitMQ 服务实现
    /// 针对嵌入式设备语音通话的信令传输优化
    /// </summary>
    public class WebRtcRabbitMQService : IWebRtcRabbitMQService
    {
        private readonly ILogger<WebRtcRabbitMQService> _logger;
        private readonly WebRtcRabbitMQOptions _options;
        private readonly RabbitMQService _baseService; // 复用基础连接管理
        private readonly object _lockObject = new();
        
        // 专用高性能信令通道
        private IModel? _signalingChannel;
        private IModel? _statusChannel;
        
        // 设备管理
        private readonly ConcurrentDictionary<string, DeviceInfo> _onlineDevices = new();
        private readonly ConcurrentDictionary<string, IWebRtcSignalingHandler> _signalingHandlers = new();
        private readonly ConcurrentDictionary<string, EventingBasicConsumer> _deviceConsumers = new();
        
        // 状态监控
        private IDeviceStatusHandler? _statusHandler;
        private EventingBasicConsumer? _statusConsumer;
        
        // 性能统计
        private readonly LatencyStats _latencyStats = new();
        private readonly MessageStats _messageStats = new();
        private readonly ConcurrentQueue<LatencyMeasurement> _latencyMeasurements = new();
        
        private bool _disposed = false;

        public WebRtcRabbitMQService(
            ILogger<WebRtcRabbitMQService> logger,
            IOptions<WebRtcRabbitMQOptions> options,
            RabbitMQService baseService)
        {
            _logger = logger;
            _options = options.Value;
            _baseService = baseService;
        }

        // ====================
        // 连接和初始化
        // ====================

        public async Task InitializeAsync()
        {
            if (!_options.Enabled)
            {
                _logger.LogInformation("WebRTC RabbitMQ 服务已禁用");
                return;
            }

            try
            {
                // 确保基础服务已初始化
                await _baseService.InitializeAsync();
                
                if (!_baseService.IsConnected)
                {
                    throw new InvalidOperationException("基础 RabbitMQ 服务连接失败");
                }

                // 创建专用通道
                await CreateSpecializedChannelsAsync();
                
                // 初始化交换机和队列
                await SetupExchangesAndQueuesAsync();
                
                _logger.LogInformation("WebRTC RabbitMQ 专用服务初始化成功");
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "WebRTC RabbitMQ 服务初始化失败");
                throw;
            }
        }

        private async Task CreateSpecializedChannelsAsync()
        {
            lock (_lockObject)
            {
                // 通过反射访问基础服务的连接（组合模式）
                var connectionField = typeof(RabbitMQService).GetField("_connection", 
                    System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance);
                var connection = connectionField?.GetValue(_baseService) as IConnection;

                if (connection == null || !connection.IsOpen)
                {
                    throw new InvalidOperationException("无法获取基础 RabbitMQ 连接");
                }

                // 创建专用高性能信令通道
                _signalingChannel = connection.CreateModel();
                _signalingChannel.BasicQos(0, _options.Performance.PrefetchCount, false);
                
                // 创建设备状态管理通道
                _statusChannel = connection.CreateModel();
                _statusChannel.BasicQos(0, 10, false);

                _logger.LogDebug("WebRTC 专用通道创建成功");
            }
        }

        private async Task SetupExchangesAndQueuesAsync()
        {
            if (_signalingChannel == null || _statusChannel == null)
                return;

            // 声明信令交换机（如果使用交换机模式）
            if (!_options.Signaling.UseDirectQueues)
            {
                _signalingChannel.ExchangeDeclare(
                    exchange: "webrtc.signaling",
                    type: ExchangeType.Direct,
                    durable: false,
                    autoDelete: false
                );
            }

            // 声明设备状态交换机
            _statusChannel.ExchangeDeclare(
                exchange: "webrtc.device.status",
                type: ExchangeType.Fanout,
                durable: false,
                autoDelete: false
            );

            // 声明设备注册队列
            var regArgs = new Dictionary<string, object>
            {
                { "x-message-ttl", 300000 }, // 5分钟过期
                { "x-max-length", 1000 }
            };

            _statusChannel.QueueDeclare(
                queue: _options.EmbeddedDevices.RegistrationQueue,
                durable: false,
                exclusive: false,
                autoDelete: false,
                arguments: regArgs
            );

            _logger.LogDebug("WebRTC 交换机和队列设置完成");
        }

        public async Task<bool> IsConnectedAsync()
        {
            return _baseService.IsConnected && 
                   _signalingChannel?.IsOpen == true && 
                   _statusChannel?.IsOpen == true;
        }

        public async Task<object> GetServiceStatusAsync()
        {
            return new
            {
                IsConnected = await IsConnectedAsync(),
                OnlineDevices = _onlineDevices.Count,
                ActiveHandlers = _signalingHandlers.Count,
                TotalMessagesSent = _messageStats.TotalSent,
                TotalMessagesReceived = _messageStats.TotalReceived,
                AverageLatency = _latencyStats.AverageLatency,
                LastUpdated = DateTime.UtcNow
            };
        }

        // ====================
        // 嵌入式设备管理
        // ====================

        public async Task<bool> RegisterDeviceAsync(string deviceId, DeviceCapabilities capabilities)
        {
            try
            {
                var deviceInfo = new DeviceInfo
                {
                    DeviceId = deviceId,
                    Capabilities = capabilities,
                    RegisterTime = DateTime.UtcNow,
                    LastHeartbeat = DateTime.UtcNow,
                    Status = "online"
                };

                _onlineDevices.TryAdd(deviceId, deviceInfo);

                // 创建设备专用队列
                await CreateDeviceQueuesAsync(deviceId);

                // 发布设备上线状态
                var statusMessage = DeviceStatusMessage.CreateOnline(deviceId, capabilities);
                await PublishDeviceStatusAsync(statusMessage);

                _logger.LogInformation("设备注册成功: {DeviceId}, 类型: {DeviceType}", 
                    deviceId, capabilities.DeviceType);

                return true;
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "设备注册失败: {DeviceId}", deviceId);
                return false;
            }
        }

        private async Task CreateDeviceQueuesAsync(string deviceId)
        {
            if (_signalingChannel == null) return;

            var queueArgs = new Dictionary<string, object>
            {
                { "x-max-priority", _options.Signaling.OfferAnswerPriority },
                { "x-message-ttl", _options.Signaling.SignalingTTL },
                { "x-max-length", _options.Signaling.MaxQueueLength },
                { "x-overflow", _options.Signaling.OverflowStrategy }
            };

            // 如果使用非持久化消息，队列也设为非持久化
            bool durable = !_options.Performance.UseNonPersistentMessages;

            // 设备接收队列（服务器发送给设备）
            var inQueueName = $"{_options.Signaling.QueuePrefix}.{deviceId}.in";
            _signalingChannel.QueueDeclare(
                queue: inQueueName,
                durable: durable,
                exclusive: false,
                autoDelete: true,
                arguments: queueArgs
            );

            // 设备发送队列（设备发送给服务器）
            var outQueueName = $"{_options.Signaling.QueuePrefix}.{deviceId}.out";
            _signalingChannel.QueueDeclare(
                queue: outQueueName,
                durable: durable,
                exclusive: false,
                autoDelete: true,
                arguments: queueArgs
            );

            _logger.LogDebug("设备队列创建成功: {DeviceId}", deviceId);
        }

        public async Task<bool> UnregisterDeviceAsync(string deviceId, string? reason = null)
        {
            try
            {
                _onlineDevices.TryRemove(deviceId, out _);

                // 停止监听
                await StopListeningAsync(deviceId);

                // 发布设备离线状态
                var statusMessage = DeviceStatusMessage.CreateOffline(deviceId, reason);
                await PublishDeviceStatusAsync(statusMessage);

                _logger.LogInformation("设备注销成功: {DeviceId}, 原因: {Reason}", deviceId, reason ?? "正常离线");
                return true;
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "设备注销失败: {DeviceId}", deviceId);
                return false;
            }
        }

        public async Task<bool> IsDeviceOnlineAsync(string deviceId)
        {
            if (!_onlineDevices.TryGetValue(deviceId, out var deviceInfo))
                return false;

            // 检查心跳超时
            var timeout = DateTime.UtcNow - deviceInfo.LastHeartbeat;
            if (timeout > _options.EmbeddedDevices.DeviceOfflineTimeout)
            {
                await UnregisterDeviceAsync(deviceId, "心跳超时");
                return false;
            }

            return true;
        }

        public async Task<DeviceStatusMessage?> GetDeviceStatusAsync(string deviceId)
        {
            if (!_onlineDevices.TryGetValue(deviceId, out var deviceInfo))
                return null;

            return new DeviceStatusMessage
            {
                DeviceId = deviceId,
                Status = deviceInfo.Status,
                ActiveCalls = deviceInfo.ActiveCalls,
                LastHeartbeat = deviceInfo.LastHeartbeat,
                Capabilities = deviceInfo.Capabilities
            };
        }

        public async Task<List<string>> GetOnlineDevicesAsync()
        {
            return _onlineDevices.Keys.ToList();
        }

        public async Task UpdateDeviceStatusAsync(string deviceId, DeviceStatusMessage status)
        {
            if (_onlineDevices.TryGetValue(deviceId, out var deviceInfo))
            {
                deviceInfo.Status = status.Status;
                deviceInfo.ActiveCalls = status.ActiveCalls;
                deviceInfo.LastHeartbeat = status.LastHeartbeat;
            }

            await PublishDeviceStatusAsync(status);
        }

        // ====================
        // WebRTC 信令发送
        // ====================

        public async Task<bool> SendOfferAsync(string fromDeviceId, string toDeviceId, WebRtcOffer offer, 
            string? sessionId = null, string? roomId = null)
        {
            var message = WebRtcSignalingMessage.CreateOffer(fromDeviceId, toDeviceId, offer, sessionId, roomId);
            return await SendSignalingMessageAsync(message);
        }

        public async Task<bool> SendAnswerAsync(string fromDeviceId, string toDeviceId, WebRtcAnswer answer, 
            string sessionId, string? roomId = null)
        {
            var message = WebRtcSignalingMessage.CreateAnswer(fromDeviceId, toDeviceId, answer, sessionId, roomId);
            return await SendSignalingMessageAsync(message);
        }

        public async Task<bool> SendIceCandidateAsync(string fromDeviceId, string toDeviceId, IceCandidate candidate, 
            string sessionId, string? roomId = null)
        {
            var message = WebRtcSignalingMessage.CreateIceCandidate(fromDeviceId, toDeviceId, candidate, sessionId, roomId);
            return await SendSignalingMessageAsync(message);
        }

        public async Task<bool> SendCallStartAsync(string fromDeviceId, string toDeviceId, string sessionId, 
            string? roomId = null)
        {
            var message = WebRtcSignalingMessage.CreateCallStart(fromDeviceId, toDeviceId, sessionId, roomId);
            return await SendSignalingMessageAsync(message);
        }

        public async Task<bool> SendCallEndAsync(string fromDeviceId, string toDeviceId, string sessionId, 
            string? roomId = null, string? reason = null)
        {
            var message = WebRtcSignalingMessage.CreateCallEnd(fromDeviceId, toDeviceId, sessionId, roomId, reason);
            return await SendSignalingMessageAsync(message);
        }

        private async Task<bool> SendSignalingMessageAsync(WebRtcSignalingMessage message)
        {
            if (_signalingChannel == null || !await IsDeviceOnlineAsync(message.ToDeviceId))
            {
                _logger.LogWarning("无法发送信令消息: 通道未连接或目标设备离线 {ToDeviceId}", message.ToDeviceId);
                return false;
            }

            try
            {
                var sendTime = DateTime.UtcNow;
                var queueName = $"{_options.Signaling.QueuePrefix}.{message.ToDeviceId}.in";

                var properties = _signalingChannel.CreateBasicProperties();
                properties.Priority = (byte)message.Priority;
                properties.Expiration = message.TTL.ToString();
                properties.DeliveryMode = _options.Performance.UseNonPersistentMessages ? (byte)1 : (byte)2;
                properties.Type = message.SignalType;
                properties.MessageId = message.Id;
                properties.Timestamp = new AmqpTimestamp(DateTimeOffset.UtcNow.ToUnixTimeSeconds());
                properties.CorrelationId = message.SessionId;

                // 添加延迟监控
                if (_options.Performance.EnableLatencyMonitoring)
                {
                    properties.Headers = new Dictionary<string, object>
                    {
                        ["sent_time"] = sendTime.ToBinary()
                    };
                }

                var json = JsonSerializer.Serialize(message);
                var body = Encoding.UTF8.GetBytes(json);

                if (_options.Signaling.UseDirectQueues)
                {
                    // 直连队列模式 - 最快路径
                    _signalingChannel.BasicPublish(
                        exchange: "",
                        routingKey: queueName,
                        basicProperties: properties,
                        body: body
                    );
                }
                else
                {
                    // 交换机路由模式
                    _signalingChannel.BasicPublish(
                        exchange: "webrtc.signaling",
                        routingKey: message.ToDeviceId,
                        basicProperties: properties,
                        body: body
                    );
                }

                // 更新统计
                var totalSent = _messageStats.TotalSent;
                Interlocked.Increment(ref totalSent);
                _messageStats.TotalSent = totalSent;
                
                if (_messageStats.MessageTypeStats.TryGetValue(message.SignalType, out var count))
                {
                    _messageStats.MessageTypeStats[message.SignalType] = count + 1;
                }
                else
                {
                    _messageStats.MessageTypeStats[message.SignalType] = 1;
                }

                _logger.LogDebug("信令消息发送成功: {SignalType} from {FromDeviceId} to {ToDeviceId}, 优先级: {Priority}", 
                    message.SignalType, message.FromDeviceId, message.ToDeviceId, message.Priority);

                return true;
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "发送信令消息失败: {SignalType} from {FromDeviceId} to {ToDeviceId}", 
                    message.SignalType, message.FromDeviceId, message.ToDeviceId);
                
                var failedSent = _messageStats.FailedSent;
                Interlocked.Increment(ref failedSent);
                _messageStats.FailedSent = failedSent;
                return false;
            }
        }

        // ====================
        // 信令监听
        // ====================

        public async Task StartListeningAsync(string deviceId, IWebRtcSignalingHandler handler)
        {
            if (_signalingChannel == null)
            {
                _logger.LogError("无法启动设备监听: 信令通道未初始化");
                return;
            }

            try
            {
                var queueName = $"{_options.Signaling.QueuePrefix}.{deviceId}.out";
                
                var consumer = new EventingBasicConsumer(_signalingChannel);
                consumer.Received += async (model, ea) =>
                {
                    var receiveTime = DateTime.UtcNow;
                    WebRtcSignalingMessage? message = null;
                    
                    try
                    {
                        var json = Encoding.UTF8.GetString(ea.Body.ToArray());
                        message = JsonSerializer.Deserialize<WebRtcSignalingMessage>(json);
                        
                        if (message != null)
                        {
                            // 计算延迟
                            if (_options.Performance.EnableLatencyMonitoring && 
                                ea.BasicProperties.Headers?.TryGetValue("sent_time", out var sentTimeObj) == true)
                            {
                                var sentTime = DateTime.FromBinary((long)sentTimeObj);
                                var latency = (receiveTime - sentTime).TotalMilliseconds;
                                RecordLatency(latency);
                            }

                            var success = await handler.HandleSignalingMessageAsync(message);
                            
                            if (success)
                            {
                                _signalingChannel.BasicAck(ea.DeliveryTag, false);
                                var totalReceived = _messageStats.TotalReceived;
                                Interlocked.Increment(ref totalReceived);
                                _messageStats.TotalReceived = totalReceived;
                            }
                            else
                            {
                                _signalingChannel.BasicNack(ea.DeliveryTag, false, false);
                            }
                        }
                    }
                    catch (Exception ex)
                    {
                        _logger.LogError(ex, "处理设备 {DeviceId} 信令消息失败", deviceId);
                        if (message != null)
                        {
                            await handler.HandleMessageFailureAsync(message, ex);
                        }
                        _signalingChannel.BasicNack(ea.DeliveryTag, false, false);
                    }
                };

                _signalingChannel.BasicConsume(
                    queue: queueName,
                    autoAck: false,
                    consumer: consumer
                );

                _signalingHandlers[deviceId] = handler;
                _deviceConsumers[deviceId] = consumer;

                _logger.LogInformation("开始监听设备 {DeviceId} 信令消息", deviceId);
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "启动设备 {DeviceId} 监听失败", deviceId);
                throw;
            }
        }

        public async Task StopListeningAsync(string deviceId)
        {
            _signalingHandlers.TryRemove(deviceId, out _);
            _deviceConsumers.TryRemove(deviceId, out _);
            
            _logger.LogDebug("停止监听设备 {DeviceId} 信令消息", deviceId);
        }

        // ====================
        // 辅助方法
        // ====================

        private void RecordLatency(double latencyMs)
        {
            _latencyMeasurements.Enqueue(new LatencyMeasurement 
            { 
                Latency = latencyMs, 
                Timestamp = DateTime.UtcNow 
            });

            // 保持最近1000条记录
            while (_latencyMeasurements.Count > 1000)
            {
                _latencyMeasurements.TryDequeue(out _);
            }

            // 更新统计
            UpdateLatencyStats();
        }

        private void UpdateLatencyStats()
        {
            var measurements = _latencyMeasurements.ToArray();
            if (measurements.Length == 0) return;

            _latencyStats.AverageLatency = measurements.Average(m => m.Latency);
            _latencyStats.MaxLatency = measurements.Max(m => m.Latency);
            _latencyStats.MinLatency = measurements.Min(m => m.Latency);
            _latencyStats.TotalMessages = measurements.Length;
            _latencyStats.HighLatencyMessages = measurements.Count(m => m.Latency > _options.Performance.LatencyThreshold);
            _latencyStats.LastUpdated = DateTime.UtcNow;
        }

        private async Task PublishDeviceStatusAsync(DeviceStatusMessage status)
        {
            if (_statusChannel == null) return;

            try
            {
                var json = JsonSerializer.Serialize(status);
                var body = Encoding.UTF8.GetBytes(json);

                var properties = _statusChannel.CreateBasicProperties();
                properties.DeliveryMode = 1; // 非持久化
                properties.MessageId = status.Id;

                _statusChannel.BasicPublish(
                    exchange: "webrtc.device.status",
                    routingKey: "",
                    basicProperties: properties,
                    body: body
                );
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "发布设备状态失败: {DeviceId}", status.DeviceId);
            }
        }

        // ====================
        // 接口实现 (简化版本)
        // ====================

        public async Task StartStatusMonitoringAsync(IDeviceStatusHandler handler)
        {
            _statusHandler = handler;
            // 实现状态监听逻辑...
        }

        public async Task StopStatusMonitoringAsync()
        {
            _statusHandler = null;
        }

        public async Task BroadcastToRoomAsync(string roomId, WebRtcSignalingMessage message, string? excludeDeviceId = null)
        {
            // 实现房间广播逻辑...
        }

        public async Task<LatencyStats> GetLatencyStatsAsync()
        {
            return _latencyStats;
        }

        public async Task<MessageStats> GetMessageStatsAsync()
        {
            _messageStats.LastUpdated = DateTime.UtcNow;
            return _messageStats;
        }

        public void Dispose()
        {
            if (_disposed) return;

            try
            {
                _signalingChannel?.Close();
                _signalingChannel?.Dispose();
                _statusChannel?.Close();
                _statusChannel?.Dispose();
                
                _onlineDevices.Clear();
                _signalingHandlers.Clear();
                _deviceConsumers.Clear();
                
                _logger.LogInformation("WebRTC RabbitMQ 服务已释放");
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "释放 WebRTC RabbitMQ 服务时发生错误");
            }
            finally
            {
                _disposed = true;
            }
        }
    }

    // ====================
    // 辅助数据结构
    // ====================

    internal class DeviceInfo
    {
        public string DeviceId { get; set; } = string.Empty;
        public DeviceCapabilities? Capabilities { get; set; }
        public DateTime RegisterTime { get; set; }
        public DateTime LastHeartbeat { get; set; }
        public string Status { get; set; } = "online";
        public int ActiveCalls { get; set; } = 0;
    }

    internal class LatencyMeasurement
    {
        public double Latency { get; set; }
        public DateTime Timestamp { get; set; }
    }
} 